
import base64
import hashlib
from typing import Optional
from fastapi import Header, Request, Depends

from utils.common import get_string_md5
from schemas.response import HttpException
from dependencies.token import get_decode_token


class RequestHeaders():
    def __init__(self,
                 request: Request,
                 x_auth_announce: str = Header(...),
                 x_auth_channel: str = Header(...),
                 x_auth_timestamp: str = Header(...),
                 x_auth_token: str = Depends(get_decode_token),
                 x_auth_version: str = Header(...),
                 x_auth_signature: str = Header(...),
                 x_auth_package: str = Header(...),
                 ):
        """
           解析请求头部信息，并做初步的鉴权认证
               :param x_auth_announce:随机数
               :param x_auth_channel:通道信息
               :param x_auth_timestamp:时间戳
               :param x_auth_token:token信息
               :param x_auth_version:版本信息
               :param x_auth_signature:签名信息
               :param x_auth_package:包名信息
           :return:解析后的请求头部信息
           """
        if x_auth_signature != self.get_sign(x_auth_announce,
                                             x_auth_channel,
                                             x_auth_timestamp,
                                             x_auth_token,
                                             x_auth_version):
            raise HttpException(403, "认证失败！")
        self._ip = request.client.host
        self._headers = get_decode_token(x_auth_token)
        if self._headers:
            self._headers.update({
                "package": x_auth_package,
                "channel": x_auth_channel,
                "version": x_auth_version,
            })
        else:
            raise HttpException(403, "认证失败！")

    def get_sign(self, announce: str, channel: str, timestamp: str, token: str, version: str) -> str:
        """
        获取签名信息，进行校验
            :param announce:随机数
            :param channel:通道信息
            :param timestamp:时间戳
            :param token:token信息
            :param version:版本信息
        :return: 签名信息
        """
        salt = 'YjYwYjY5YzUyMGFlMTU3MDhmZjVlZDAxMzNiZThiYzk='
        sign = base64.b64encode(get_string_md5(f'{announce}{channel}{timestamp}{token}{version}{salt}').encode('utf-8'))
        return sign.decode('utf-8')

    @property
    def headers(self) -> Optional[dict]:
        return self._headers

    @property
    def phone(self) -> Optional[str]:
        return self._headers.get("phone")

    @property
    def user_id(self) -> Optional[str]:
        return self._headers.get("user_id")

    @property
    def id(self) -> Optional[str]:
        return self._headers.get("id")

    @property
    def version(self) -> Optional[str]:
        return self._headers.get("version")

    @property
    def channel(self) -> Optional[str]:
        return self._headers.get("channel")

    @property
    def package(self) -> Optional[str]:
        return self._headers.get("package")

    @property
    def ip(self) -> Optional[str]:
        return self._ip
